/**
 *  Initializes the map element on the canvas view.
 *  @param {google.maps.LatLng} centerLatLng - center point for the map.
 *  @param {int} zoom - Zoom level to initialize the map with.
 */
function initializeMap( centerLatLng, zoom ) {
  // sets the map options 
  var options = {
    zoom: zoom * 1,
    center: centerLatLng,
    mapTypeControl: false,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    scrollwheel: false
  };
  
  // render the map with the options
  map = new google.maps.Map($("#map_canvas")[0], options);
  
  // add a listener to the drag end event to trigger a webservice call
  google.maps.event.addListener(map, 'dragend', onMoveEnd);
  // add a listener for zooming to trigger a webservice call
  addZoomListener();
}

/**
 *  Adds a listener for zooming to trigger a webservice call
 *  NOTE: used the bounds_changed event due to problems caused by the zoom-1+1 workaround for the map div resize().
 */
function addZoomListener() {
  google.maps.event.addListener(map, 'bounds_changed', function() { 
    // if the zoom has changed, trigger a webservice call
    if (getZoom() != map.getZoom()) { onMoveEnd(); }
  });
}






/** EVENTS **/

/**
 *  Event fired on map drag end to get appropriate results.
 */
function onMoveEnd() {
  if (bounds == map.getBounds()) return;
  bounds = map.getBounds();
  setZoom( map.getZoom() );
  
  setFuelType($("#fueltypes").val());
  getResults( getFuelType() );

  resize();
}





/** MAP UI FUNCTIONS

/**
 *  Place marker on the map.
 *  @param {google.maps.LatLng} markerLatLng - Point at which the marker should be placed.
 *  @param {string} siteName - Name of the site for the marker.
 *  @param {string} colour - Colour of the marker image.
 *  @param {string} letter - Letter to be shown on the marker image.
 */
function placeMarker (markerLatLng, siteName, colour, letter) {  
  // create marker and add it to the map.
  var marker = new google.maps.Marker({
      position: markerLatLng, 
      icon: "http://petrolpricetracker.googlecode.com/svn/trunk/gadget/img/pin_"+colour+"_"+letter+".gif",
      clickable: false,
      map: map,
      title: siteName
  });
  
  // manual add ONLY to keep track of markers for easy clearing
  map.addMarker(marker);
}

/**
 *  Whenever the container div is resized, this method is called to maintain a constant center
 *  for the map. If this isn't called, whenever something is centered after the div has been
 *  resized, the map will focus off-center.
 */
function resize() {
  google.maps.event.trigger(map, 'resize');
  // hack to work around map centering - NECESSARY
  map.setZoom( map.getZoom() - 1 );
  map.setZoom( map.getZoom() + 1 );
}

/**
 *  Clear map of any and all markers.
 */
function clearMap() {
  map.clearMarkers();
}

/**
 *  Sets the map center.
 *  @param {google.maps.LatLng} center - The point on which to center the map.
 *	@oaran opt {int} zoom - Zoom level to set the map view to.
 */
function setCenter( targetCenter, zoom ) {
  showHideResultElements(true);
  center = targetCenter;
  map.setCenter(targetCenter, zoom === undefined ? map.getZoom() : zoom);
  onMoveEnd();
}

/**
 *	Set the bounds to scale the map to.
 *  @param {google.maps.LatLngBounds} bounds - Bounds to fit the map to.
 */
function setBounds( bounds ) {
  map.fitBounds( bounds );
  // hack to circumvent the zoom out from the fitBounds call.
  map.setZoom(map.getZoom() + 1);
}






/** GOOGLE MAPS NECESSARY WORKAROUND TO TRACK MARKERS **/
/** 
 *  IMPORTANT NOTICE:
 *  If markers start breaking, make sure that Google haven't changed the Maps implementation
 *  to break any of these methods. Prototypes add methods to the class - if they have their own
 *  implementation, these will break.
 */
google.maps.Map.prototype.markers = new Array();

google.maps.Map.prototype.addMarker = function(marker) {
    this.markers[this.markers.length] = marker;
};

google.maps.Map.prototype.getMarkers = function() {
    return this.markers
};

google.maps.Map.prototype.clearMarkers = function() {
    for(var i=0; i<this.markers.length; i++){
        this.markers[i].setMap(null);
    }
    this.markers = new Array();
};